﻿/*****************************************************************
JQUERY OFICIAL DEL FRAMEWORK JERTI 1.0.0 PARA CAMPOS AUTOCOMPLETE
CREADO POR: JUAN MIGUEL PEREZ PINEDA
REVISION: JULIO - 2012
*****************************************************************/
(function ($) {
    /*Creamos el mapeo de las vocales con sus acentos para las busquedas en los campos y poder omitir los acentos*/
    var accentMap = { "á": "a", "é": "e", "í": "i", "ó": "o", "ú": "u", "Á": "A", "É": "E", "Í": "I", "Ó": "O", "Ú": "U" };

    /*****************************************************************
    FX ENCARGADA DE MARCAR UN INPUT COMO AUTOCOMPLEMENTADO, PERO UTILIZANDO CACHE EN EL LADO DEL CLIENTE
    *****************************************************************/
    $.fn.autocompletadoWithCache = function (optACWC) {
        var $self = this;

        //Establecemos los valores por defecto
        optACWC_def = {
            data: null,
            autoFocus: false,
            delay: 0,
            minParam: 1,
            dependiente: false
        }
        var optACWCParam = jQuery.extend(optACWC_def, optACWC);

        /*Ahora hacemos la llamada a la funcion de jQueryUI para el widget de Autocomplete*/
        $self.autocomplete({
            delay: optACWCParam.delay,
            autoFocus: optACWCParam.autoFocus,
            minLength: optACWCParam.minParam,
            source: function (request, response) {
                var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i"),
                    $objDep = $($self.attr('data-jerti-depende')),
                    arrFilter;

                /*Analizamos si este este campo ha sido marcado con dependencia de otro campo o no*/
                if ($objDep.length == 0) {           //El source del campo no depende de nadie
                    /*Filtramos los resultados del array en un nuevo array*/
                    arrFilter = $.grep(optACWCParam.data, function (elm) {
                        return matcher.test(elm.Text) || matcher.test($.fxNormalizarString(elm.Text));
                    })
                } else {                            //Hay que filtrar el resultado
                    arrFilter = $.grep(optACWCParam.data, function (elm) {
                        return elm.Filter == $objDep.val() && (matcher.test(elm.Text) || matcher.test($.fxNormalizarString(elm.Text)));
                    })
                }
                
                /*Preparamos la respuesta devuelta al control*/
                response($.map(arrFilter, function (elm, i) {
                    if (i < 80)
                        return {
                            label: $.fxNormalizarString(elm.Text).replace(
                                new RegExp(
                                    "(?![^&;]+;)(?!<[^<>]*)(" +
                                    $.ui.autocomplete.escapeRegex(request.term) +
                                    ")(?![^<>]*>)(?![^&;]+;)", "gi"
                                ), '<strong class="j-highlight-autocomplete">$1</strong>'),
                            value: elm.Text,
                            dataValue: elm.Value
                        };
                }));
            },
            select: function (event, ui) {
                /*Agregamos el valor al padre*/
                $($(this).attr('data-jerti-parent')).val(ui.item.dataValue);
            },
            change: function (event, ui) {
                if (!ui.item) {
                    /*Como el items es válido pasaremos a marcar como SELECTED en el Source*/
                    var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val()) + "$", "i"),
                        valid = false;

                    if (!valid) {
                        // remove invalid value, as it didn't match anything
                        $(this).val("");
                        $($(this).attr('data-jerti-parent')).val('');
                        $self.data("autocomplete").term = "";
                        return false;
                    }
                }
            }
        });

        /*Preparamos la renderizacion de los items en el campo*/
        $self.data("autocomplete")._renderItem = function (ul, item) {
            return $("<li></li>")
                .data("item.autocomplete", item)
                .append("<a>" + item.label + "</a>")
                .appendTo(ul);
        };
    }

    /*****************************************************************
    FX ENCARGADA DE MARCAR UN INPUT COMO AUTOCOMPLEMENTADO (SIN UTILIZAR CACHE)
    *****************************************************************/
    $.fn.autocompletado = function (optAC) {
        var $self = this,
            $idLoading = $($self.attr('data-jerti-loading'));

        //Establecemos los valores por defecto
        optAC_def = {
            data: null,
            autoFocus: false,
            delay: 0,
            minParam: 1,
            dependiente: false
        }
        var optACParam = jQuery.extend(optAC_def, optAC);

        /*Ahora hacemos la llamada a la funcion de jQueryUI para el widget de Autocomplete*/
        $self.autocomplete({
            delay: optACParam.delay,
            autoFocus: optACParam.autoFocus,
            minLength: $self.attr('data-jerti-minparam'),
            source: function (request, response) {
                if ($idLoading) $idLoading.show();
                $.ajax({
                    url: $self.attr('data-jerti-loadItems'),
                    type: 'POST',
                    data: { text: request.term }
                })
                .done(function (data) { response(data.Items);})
                .fail(function (jqXhr, textStatus, errorThrown) {
                    if ($idLoading) $idLoading.hide();                          //Detenemos la animacion de carga
                    $.handlerAjaxFail(jqXhr, textStatus, errorThrown);          /*Ahora le pasamos los datos la manejador de errores*/
                })
                .always(function () { 
                    if ($idLoading) $idLoading.hide();                          //Detenemos la animacion de carga
                });
            },
            select: function (event, ui) {
                $($(this).attr('data-jerti-parent')).val(ui.item.Value);    /*Agregamos el valor al padre*/
                var $p = $($self.attr('data-jerti-parent'));
                $p.trigger('itemSelected', [ui.item]);
            },
            change: function (event, ui) {
                if (!ui.item) {
                    /*Como el items es válido pasaremos a marcar como SELECTED en el Source*/
                    var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val()) + "$", "i"),
                        valid = false;

                    if (!valid) {
                        // remove invalid value, as it didn't match anything
                        $(this).val("");
                        $($(this).attr('data-jerti-parent')).val('');
                        $self.data("autocomplete").term = "";
                        return false;
                    }
                }
            }
        }).data("autocomplete")._renderItem = function (ul, item) {
            $idLoading.show();
            var $p = $($self.attr('data-jerti-parent')),
                x = $p.triggerHandler('renderItemAutoComplete', [ul, item]);
                $idLoading.hide();
            if (x)
                return x
            else
                return $("<li></li>")
                    .data("item.autocomplete", item)
                    .append("<a>" + item.Text + "</a>")
                    .appendTo(ul);
        };
    }

    /*****************************************************************
    FX PRIVADA PARA NORMALIZAR UN STRING, CONVIRTIENDO LOS ACENTOS A PALABRAS SIN ACENTO
    *****************************************************************/
    $.fxNormalizarString = function (term) {
        var ret = "";
        for (var i = 0; i < term.length; i++) {
            ret += accentMap[term.charAt(i)] || term.charAt(i);
        }
        return ret;
    };

})(jQuery);